{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "979e08a7",
   "metadata": {},
   "source": [
    "# Live-view browser tool with Browser-Use SDK\n",
    "\n",
    "## Overview\n",
    "\n",
    "In this tutorial we will learn how to use Browser-Use to interact with Amazon Bedrock Agentcore Browser tool and view the browser live.\n",
    "\n",
    "\n",
    "### Tutorial Details\n",
    "\n",
    "\n",
    "| Information         | Details                                                                          |\n",
    "|:--------------------|:---------------------------------------------------------------------------------|\n",
    "| Tutorial type       | Conversational                                                                   |\n",
    "| Agent type          | Single                                                                           |\n",
    "| Agentic Framework   | Browser-Use                                                                      |\n",
    "| LLM model           | Anthropic Claude 3.5 Sonnet                                                      |\n",
    "| Tutorial components | Using Browser-Use to interact with browser tool and view it live                 |\n",
    "| Tutorial vertical   | vertical                                                                         |\n",
    "| Example complexity  | Easy                                                                             |\n",
    "| SDK used            | Amazon BedrockAgentCore Python SDK, Browser-Use                                  |\n",
    "\n",
    "### Tutorial Architecture\n",
    "\n",
    "In this tutorial we will describe how to use Browser-Use with browser tool and view the browser live.  \n",
    "\n",
    "In our example we will send natural language instructions to the Browse-Use agent to perform tasks on the Bedrock Agentcore browser and view the browser live.\n",
    "\n",
    "<div style=\"text-align:left\">\n",
    "    <img src=\"images/architecture_runtime.png\" width=\"50%\"/>\n",
    "</div>\n",
    "\n",
    "### Tutorial Key Features\n",
    "\n",
    "* Using browser tool and view it live \n",
    "* Using Browser-Use with browser tool"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ee57d729",
   "metadata": {},
   "source": [
    "## Prerequisites\n",
    "\n",
    "To execute this tutorial you will need:\n",
    "* Python 3.11+\n",
    "* AWS credentials\n",
    "* Amazon Bedrock AgentCore SDK\n",
    "* Browser-Use SDK "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "39acfd57",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install -r requirements.txt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0752b660",
   "metadata": {},
   "source": [
    "## Using Browser-Use with Bedrock Agentcore Browser tool with live view\n",
    "\n",
    "Here, we will use a helper class `BrowserViewerServer` to connect via the Amazon DCV SDK to the Bedrock Agentcore browser tool.\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "68dc257e",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%writefile live_view_with_browser_use.py\n",
    "from browser_use import Agent\n",
    "from browser_use.browser.session import BrowserSession\n",
    "from bedrock_agentcore.tools.browser_client import BrowserClient\n",
    "from browser_use.browser import BrowserProfile\n",
    "from langchain_aws import ChatBedrockConverse\n",
    "from rich.console import Console\n",
    "from rich.panel import Panel\n",
    "from contextlib import suppress\n",
    "import argparse\n",
    "import sys\n",
    "sys.path.append(\"../interactive_tools\")\n",
    "from browser_viewer import BrowserViewerServer\n",
    "import asyncio\n",
    "from boto3.session import Session\n",
    "\n",
    "console = Console()\n",
    "\n",
    "boto_session = Session()\n",
    "region = boto_session.region_name\n",
    "\n",
    "\n",
    "async def run_browser_task(\n",
    "    browser_session: BrowserSession, bedrock_chat: ChatBedrockConverse, task: str\n",
    ") -> None:\n",
    "    \"\"\"\n",
    "    Run a browser automation task using browser_use\n",
    "\n",
    "    Args:\n",
    "        browser_session: Existing browser session to reuse\n",
    "        bedrock_chat: Bedrock chat model instance\n",
    "        task: Natural language task for the agent\n",
    "    \"\"\"\n",
    "    try:\n",
    "        # Show task execution\n",
    "        console.print(f\"\\n[bold blue]🤖 Executing task:[/bold blue] {task}\")\n",
    "\n",
    "        # Create and run the agent\n",
    "        agent = Agent(task=task, llm=bedrock_chat, browser_session=browser_session)\n",
    "\n",
    "        # Run with progress indicator\n",
    "        with console.status(\n",
    "            \"[bold green]Running browser automation...[/bold green]\", spinner=\"dots\"\n",
    "        ):\n",
    "            await agent.run()\n",
    "\n",
    "        console.print(\"[bold green]✅ Task completed successfully![/bold green]\")\n",
    "\n",
    "    except Exception as e:\n",
    "        console.print(f\"[bold red]❌ Error during task execution:[/bold red] {str(e)}\")\n",
    "        import traceback\n",
    "\n",
    "        if console.is_terminal:\n",
    "            traceback.print_exc()\n",
    "\n",
    "\n",
    "async def live_view_with_browser_use(prompt, region=\"us-west-2\"):\n",
    "    \"\"\"\n",
    "    Main function that demonstrates live browser viewing with Agent automation.\n",
    "\n",
    "    Workflow:\n",
    "    1. Creates Amazon Bedrock AgentCore browser client in us-west-2 region\n",
    "    2. Waits for browser initialization (10-second required delay)\n",
    "    3. Starts DCV-based live viewer server on port 8000 with browser control\n",
    "    4. Configures multiple display size options (720p to 1440p)\n",
    "    5. Establishes browser session for AI agent automation via CDP WebSocket\n",
    "    6. Executes AI-driven tasks using Claude 3.5 Sonnet model\n",
    "    7. Properly closes all sessions and stops browser client\n",
    "\n",
    "    Features:\n",
    "    - Real-time browser viewing through web interface\n",
    "    - Manual take/release control functionality\n",
    "    - AI automation with browser-use library\n",
    "    - Configurable display layouts and sizes\n",
    "    \"\"\"\n",
    "    console.print(\n",
    "        Panel(\n",
    "            \"[bold cyan]Browser Live Viewer[/bold cyan]\\n\\n\"\n",
    "            \"This demonstrates:\\n\"\n",
    "            \"• Live browser viewing with DCV\\n\"\n",
    "            \"• Configurable display sizes (not limited to 900×800)\\n\"\n",
    "            \"• Proper display layout callbacks\\n\\n\"\n",
    "            \"[yellow]Note: Requires Amazon DCV SDK files[/yellow]\",\n",
    "            title=\"Browser Live Viewer\",\n",
    "            border_style=\"blue\",\n",
    "        )\n",
    "    )\n",
    "\n",
    "    try:\n",
    "        # Step 1: Create browser session\n",
    "        client = BrowserClient(region)\n",
    "        client.start()\n",
    "        \n",
    "        ws_url, headers = client.generate_ws_headers()\n",
    "\n",
    "        # Step 2: Start viewer server\n",
    "        console.print(\"\\n[cyan]Step 3: Starting viewer server...[/cyan]\")\n",
    "        viewer = BrowserViewerServer(client, port=8000)\n",
    "        viewer_url = viewer.start(open_browser=True)\n",
    "\n",
    "        # Step 3: Show features\n",
    "        console.print(\"\\n[bold green]Viewer Features:[/bold green]\")\n",
    "        console.print(\n",
    "            \"• Default display: 1600×900 (configured via displayLayout callback)\"\n",
    "        )\n",
    "        console.print(\"• Size options: 720p, 900p, 1080p, 1440p\")\n",
    "        console.print(\"• Real-time display updates\")\n",
    "        console.print(\"• Take/Release control functionality\")\n",
    "\n",
    "        console.print(\"\\n[yellow]Press Ctrl+C to stop[/yellow]\")\n",
    "\n",
    "        # Step 4: Use browser-use to interact with browser\n",
    "        # Create persistent browser session and model\n",
    "        browser_session = None\n",
    "        bedrock_chat = None\n",
    "\n",
    "        try:\n",
    "            # Create browser profile with headers\n",
    "            browser_profile = BrowserProfile(\n",
    "                headers=headers,\n",
    "                timeout=1500000,  # 150 seconds timeout\n",
    "            )\n",
    "\n",
    "            # Create a browser session with CDP URL and keep_alive=True for persistence\n",
    "            browser_session = BrowserSession(\n",
    "                cdp_url=ws_url,\n",
    "                browser_profile=browser_profile,\n",
    "                keep_alive=True,  # Keep browser alive between tasks\n",
    "            )\n",
    "\n",
    "            # Initialize the browser session\n",
    "            console.print(\"[cyan]🔄 Initializing browser session...[/cyan]\")\n",
    "            await browser_session.start()\n",
    "\n",
    "            # Create ChatBedrockConverse once\n",
    "            bedrock_chat = ChatBedrockConverse(\n",
    "                model_id=\"anthropic.claude-3-5-sonnet-20240620-v1:0\",\n",
    "                region_name=region,\n",
    "            )\n",
    "\n",
    "            console.print(\n",
    "                \"[green]✅ Browser session initialized and ready for tasks[/green]\\n\"\n",
    "            )\n",
    "\n",
    "            task = prompt\n",
    "\n",
    "            await run_browser_task(browser_session, bedrock_chat, task)\n",
    "\n",
    "        finally:\n",
    "            # Close the browser session\n",
    "            if browser_session:\n",
    "                console.print(\"\\n[yellow]🔌 Closing browser session...[/yellow]\")\n",
    "                with suppress(Exception):\n",
    "                    await browser_session.close()\n",
    "                console.print(\"[green]✅ Browser session closed[/green]\")\n",
    "   \n",
    "    except Exception as e:\n",
    "        console.print(f\"\\n[red]Error: {e}[/red]\")\n",
    "        import traceback\n",
    "        traceback.print_exc()\n",
    "    finally:\n",
    "        console.print(\"\\n\\n[yellow]Shutting down...[/yellow]\")\n",
    "        if \"client\" in locals():\n",
    "            client.stop()\n",
    "            console.print(\"✅ Browser session terminated\")\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    parser = argparse.ArgumentParser()\n",
    "    parser.add_argument(\"--prompt\", required=True, help=\"Browser Search instruction\")\n",
    "    parser.add_argument(\"--region\", default=\"us-west-2\", help=\"AWS region\")\n",
    "    args = parser.parse_args()\n",
    "\n",
    "    asyncio.run(live_view_with_browser_use(\n",
    "        args.prompt, args.region\n",
    "    ))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bca56bc8",
   "metadata": {},
   "source": [
    "#### Running the script\n",
    "Run the script below. After the script runs (will take sometime depending on the complexity of the prompt), scroll through the output to see the result of the actions taken. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ad636c86",
   "metadata": {},
   "outputs": [],
   "source": [
    "!python live_view_with_browser_use.py --prompt \"Search for macbooks on amazon.com and extract the details of the first one\" "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b531e274",
   "metadata": {},
   "source": [
    "## What happened behind the scenes? \n",
    "* You instantiated a Browser client and started a session\n",
    "* Then you used the `BrowserViewerServer` to connect to the browser session to view the session locally\n",
    "* Then you created a Browser-Use Agent and passed the details of the browser session to it\n",
    "* You then sent natural language instructions to the Browser-Use agent and saw the actions live\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8658cafb",
   "metadata": {},
   "source": [
    "# Congratulations! "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "amazon-bedrock-agentcore-samples",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
